// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using System;
using System.Collections.Generic;
using KnessetCore.Engines;
using KnessetCore.Fetchers;
using KnessetCore.Members.Views;
using KnessetCore.Parser;
using KnessetCore.Updaters;
using KnessetCore.Utils;
using KnessetUpdater.Properties;
using log4net;
using log4net.Config;

namespace KnessetCore.Service
{
	public class Integration
	{
		/// <summary>
		/// Used in order to log data.
		/// </summary>
		private readonly ILog logger = LogManager.GetLogger("KnessetCore.Engine"); 
		/// <summary>
		/// Will update new members and add them to the the db on a daily basis.
		/// </summary>
		private FetcherParserUpdaterEngine<string, ICollection<MemberView>> newMemberUpdaterEngine;
		/// <summary>
		/// Updates the attendence list on a hourly basis.
		/// </summary>
		private FetcherParserUpdaterEngine<string, Triplet<IDictionary<string, bool>, TimeSpan, DateTime>>
			attendingSheetUpdaterEngine;



		static void Main(string[] args)
		{
			

			// Run it with several different parameters.
			if (args.Length > 0)
			{
				XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));

				Integration integrationProcess = new Integration();
				if (args[1].Equals("-attending"))
				{
					integrationProcess.CheckAttendingMember();
				} 
				else if (args[1].Equals("-newmember"))
				{
					integrationProcess.CheckNewMember();
				}
				else
				{
					Console.WriteLine("Unknown paramater. Exiting!");
				}
			}
			else 
			{
				Console.WriteLine("Not enough arguments. Exiting!");
			}
			
		}

		/// <summary>
		/// Create a new integration object.
		/// </summary>
		public Integration()
		{
			// Initialize new member engine.
			String newMembersUrl = Settings.Default.NewMembersUrl;
			HtmlFetcher membersFetcher = new HtmlFetcher(newMembersUrl);
			ParseMembersList parseMembersList = new ParseMembersList();
			NewMembersUpdater newMembersUpdater = new NewMembersUpdater();

			newMemberUpdaterEngine = new FetcherParserUpdaterEngine<String, ICollection<MemberView>>(membersFetcher, parseMembersList, newMembersUpdater);

			// Initialize attending member engine.
			String attendenceSheetUrl = Settings.Default.AttendenceSheetUrl;
			HtmlFetcher attendenceFetcher = new HtmlFetcher(attendenceSheetUrl);
			ParsePresentList parsePresentList = new ParsePresentList();
			AttendingUpdater attendingUpdater = new AttendingUpdater();

			attendingSheetUpdaterEngine = new FetcherParserUpdaterEngine<String, Triplet<IDictionary<string, bool>, TimeSpan, DateTime>>(attendenceFetcher, parsePresentList, attendingUpdater);
		}

		public void CheckNewMember()
		{
			// Start new members updater engine. The engine check for new knesset members everyday at the beginning
			// of the day.
			logger.Debug("Running scheduled task: CheckNewMember");
			newMemberUpdaterEngine.Start();
			logger.Debug("Finished running scheduled task: CheckNewMember");
		}
		/// <summary>
		/// Run attending members engine once.
		/// </summary>
		public void CheckAttendingMember()
		{
			
			logger.Debug("Running scheduled task: CheckAttendingMember");
			// Start new attendence sheet updater. The engine will check for attendence of the knesset members every 30
			// minutes.
			attendingSheetUpdaterEngine.Start();      
			logger.Debug("Finished running scheduled task: CheckAttendingMember");
		}

		public void Integrate()
		{
			// Start new members updater engine. The engine check for new knesset members everyday at the beginning
			// of the day.

			String newMembersUrl = Settings.Default.NewMembersUrl;
			HtmlFetcher membersFetcher = new HtmlFetcher(newMembersUrl);
			ParseMembersList parseMembersList = new ParseMembersList();
			NewMembersUpdater newMembersUpdater = new NewMembersUpdater();

			newMemberUpdaterEngine = new FetcherParserUpdaterEngine<String, ICollection<MemberView>>(membersFetcher, parseMembersList, newMembersUpdater);
			long day = 1000 * 60 * 60 * 24;
			newMemberUpdaterEngine.Start((long)0, day);

			// Start new attendence sheet updater. The engine will check for attendence of the knesset members every 30
			// minutes.
			String attendenceSheetUrl = Settings.Default.AttendenceSheetUrl;
			HtmlFetcher attendenceFetcher = new HtmlFetcher(attendenceSheetUrl);
			ParsePresentList parsePresentList = new ParsePresentList();
			AttendingUpdater attendingUpdater = new AttendingUpdater();

			attendingSheetUpdaterEngine = new FetcherParserUpdaterEngine<String, Triplet<IDictionary<string, bool>, TimeSpan, DateTime>>(attendenceFetcher, parsePresentList, attendingUpdater);
			// Check attendence list every x minutes. Convert it to milliseconds.
			long checkEveryXMilliseconds = Settings.Default.CheckAttendenceEveryXMinutes * 60 * 1000;

			attendingSheetUpdaterEngine.Start(0, checkEveryXMilliseconds);      
		}
	}
}
